package com.techusn.json.fromat.base.seriallize;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.techusn.json.fromat.base.annotation.FormatSerialize;
import com.techusn.json.fromat.base.strategy.FormatStrategy;
import com.techusn.json.fromat.base.strategy.factory.FormatStrategyFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;

/**
 * 序列化
 * @author chenYX
 * @date 2021/8/16 9:21
 * @description
 */
public class PatternFormatSerialize extends JsonSerializer<Object> implements ContextualSerializer {
    private static final Logger log = LoggerFactory.getLogger(PatternFormatSerialize.class);
    /**
     * 保证只有一个 PatternFormatSerialize
     */
    private static final PatternFormatSerialize SINGLETON = new PatternFormatSerialize();

    /**
     * 一个缓存用户快速的查找到对应的对应的序列化策略
     * key className+filedName ->  value  FormatStrategy
     */
    private static final HashMap<String, FormatSerialize> CLASS_FILED_TO_SERIALIZE = new HashMap<>();

    @Override
    public void serialize(Object object, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

        String currentName = jsonGenerator.getOutputContext().getCurrentName();
        Object currentValue = jsonGenerator.getCurrentValue();
        Class<?> aClass = currentValue.getClass();
        try {
            FormatSerialize formatSerialize = CLASS_FILED_TO_SERIALIZE.get(aClass.getName() + currentName);
            if (formatSerialize != null) {
                String key = formatSerialize.key();
                String[] attach = formatSerialize.attach();
                
                FormatStrategy formatStrategy = FormatStrategyFactory.getStrategy(key);
                if (formatStrategy != null) {
                    object = formatStrategy.formatData(object, attach);
                }
                jsonGenerator.writeObject(object);
            }
        } catch (Exception e) {
            log.error("自定义序列化失败{}:{}->{}",aClass.getName(),currentName,e.getMessage(),e);
            jsonGenerator.writeObject(object);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        FormatSerialize formatSerialize = beanProperty.getAnnotation(FormatSerialize.class);
        Class<?> aClass = beanProperty.getMember().getDeclaringClass();
        String name = beanProperty.getName();
        if (formatSerialize != null){
            CLASS_FILED_TO_SERIALIZE.put(aClass.getName() + name,formatSerialize);
        }
        return SINGLETON;
    }
}
